#include "NumStr.h"

#include <QDebug>
#include "earthquake_global.h"
#include "ppc_impl.h"

NumStr::tpFormat NumStr::m_nformat_s = NumStr::F_FIXED;
 NumStr::tpAlign NumStr::m_align_s = NumStr::A_RIGHT;
 unsigned int NumStr::m_precision_s = 3;
 unsigned int NumStr::m_width_s = 0;
 char NumStr::m_fill_char_s = '.';

NumStr::NumStr()
{
    usingDefault();
}

NumStr::NumStr(
       const unsigned int& width     ,
       const      tpAlign& tag_align ,
       const unsigned int& prec      ,
       const     tpFormat& tag_format
       ) :
    m_nformat(tag_format),
    m_align(tag_align),
    m_precision(prec),
    m_width(width)
{

}

void NumStr::setPrecision(const unsigned int& p)
{
    m_precision = p;
}

void NumStr::setFormat( const tpFormat& f )
{
    m_nformat = f;
}

void NumStr::setAlign(const tpAlign& a)
{
    m_align = a;
}

void NumStr::setWidth(const unsigned int& w)
{
    m_width = w;
}


NumStr::tpAlign NumStr::align(void) const
{
    return m_align;
}


unsigned int NumStr::width(void)  const
{
    return m_width;
}

NumStr::tpFormat NumStr::format(void) const
{
    return m_nformat;
}

unsigned int NumStr::precision(void) const
{
    return m_precision;
}

void NumStr::resetDefault( void )
{
      m_nformat_s = NumStr::F_FIXED;
        m_align_s = NumStr::A_RIGHT;
    m_precision_s = 3;
        m_width_s = 0;
}

void NumStr::usingDefault ( void )
{
        m_align = m_align_s;
      m_nformat = m_nformat_s;
    m_precision = m_precision_s;
        m_width = m_width_s;
}

string NumStr::fromDouble(const double& d)
{
    return m_conv(d,m_nformat_s,m_align_s,m_precision_s,m_width_s);
}

string NumStr::fromInt(const int& i)
{
    return m_conv(double(i),m_nformat_s,m_align_s,0,m_width_s);
}

string NumStr::conv(const string& s, const string &t) const
{
    string str = m_conv(s,m_align,m_width,t);
    return str;
}

string NumStr::fromString(const string& s, const string &t)
{
    return m_conv(s,m_align_s,m_width_s,t);
}

string NumStr::conv(const double& n_double) const
{
    return m_conv(n_double,m_nformat,m_align,m_precision,m_width);
}

string NumStr::conv( const bool& b ) const
{
    if (b == true)
        return m_conv(string("(1)"),m_align,3,string(""));
    else
        return m_conv(string("(0)"),m_align,3,string(""));
}

string NumStr::fromBool( const bool& b )
{
    if (b == true)
        return m_conv(string("(1)"),m_align_s,3,string(""));
    else
        return m_conv(string("(0)"),m_align_s,3,string(""));
}

string NumStr::conv(const int& n_int) const
{
    return m_conv(double(n_int),m_nformat,m_align,0,m_width);
}

string NumStr::conv( const long unsigned int &i ) const
{
    return m_conv(double(i),m_nformat,m_align,0,m_width);
}

string NumStr::fromInt( const long unsigned int &i )
{
    return m_conv(double(i),m_nformat_s,m_align_s,0,m_width_s);
}

string NumStr::m_conv(const  string& s,
                      const tpAlign& a,
                        unsigned int w,
                      const  string& t
                      )
{
    int nbchar_s = s.size();
    int nbchar_t = t.size();
    if (w == 0)
    {
        return s;
    }
    if (nbchar_s > w)
    {
        string str = s.substr(0,int(w)-nbchar_t)+t;
        return (str);
    }
    else if (nbchar_s == w)
    {
        return s;
    }
    else
    {
        int nblank = w-nbchar_s;
        if (a == A_LEFT)
        {
            return(string(nblank,m_fill_char_s)+s);
        }
        else if (a == A_RIGHT)
        {
            return(s+string(nblank,m_fill_char_s));
        }
    }
    return "";
}

string NumStr::m_conv(const double& n_double,
                           tpFormat f,
                            tpAlign a,
                       unsigned int p,
                       unsigned int w)
{
    ostringstream sstrea;

    sstrea.precision(p);
    sstrea.width(w);

    switch (a)
    {
    case NumStr::A_LEFT :
        sstrea.setf(ios_base::left,ios_base::adjustfield);
        break;
    case NumStr::A_RIGHT :
        sstrea.setf(ios_base::right,ios_base::adjustfield);
        break;
    }
    switch (f)
    {
    case NumStr::F_SCIENTIFIC:
        sstrea.setf(ios_base::scientific,ios_base::floatfield);
        break;
    case NumStr::F_FIXED:
        sstrea.setf(ios_base::fixed,ios_base::floatfield);
        break;
    }

    sstrea << n_double;

    return sstrea.str();
}

v_string NumStr::conv(v_long& vl)
{
	v_double vd;
	v_long::iterator r;
	for (r=vl.begin(); r!=vl.end(); r++)
	{
		vd.push_back(double(*r));
	}
    return(conv(vd));
}

v_string NumStr::conv(v_ulong& vu)
{
	v_double vd;
	v_ulong::iterator r;
	for (r=vu.begin(); r!=vu.end(); r++)
	{
		vd.push_back(double(*r));
	}
    return(conv(vd));
}

v_string NumStr::conv(v_double& vd)
{	
	v_string vs;
	v_double::iterator r;
	for (r=vd.begin(); r!=vd.end(); r++)
	{
        vs.push_back(conv(*r));
	}
	return(vs);
}

m_string NumStr::conv(m_ulong& mu)
{
	m_string ms;
	m_ulong::iterator r;
	for (r=mu.begin(); r!=mu.end(); r++)
	{
        ms.push_back(conv(*r));
	}
	return(ms);
}

m_string NumStr::conv(m_long& ml)
{
	m_string ms;
	m_long::iterator r;
	for (r=ml.begin(); r!=ml.end(); r++)
	{
        ms.push_back(conv(*r));
	}
	return(ms);
}

m_string NumStr::conv(m_double& md)
{
	m_string ms;
	m_double::iterator r;
	for (r=md.begin(); r!=md.end(); r++)
	{
        ms.push_back(conv(*r));
	}
	return(ms);
}

void NumStr::print(ostream& os)
{
	os<<"Precisione      : "<< m_precision<<'\n';
	os<<"Larghezza campo : "<< m_width<<'\n';
    if (m_align==A_LEFT)
	{
	os<<"Allineamento    : "<< "left"<<'\n';
	}
    if (m_align==A_RIGHT)
	{
	os<<"Allineamento    : "<< "right"<<'\n';
	}

    if (m_nformat==F_FIXED)
	{
	os<<"Formato         : "<< "fixed"<<'\n';
	}
    if (m_nformat==F_SCIENTIFIC)
	{
	os<<"Formato         : "<< "scientific"<<'\n';
	}
}

void NumStr::setFillChar (char fill_c)
{
    m_fill_char_s = fill_c;
}
